package jjn.round1;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author Jjn
 * @since 2022/8/26 23:20
 */
public class LeetCode567_PermutationInString {
    public boolean checkInclusion(String s1, String s2) {
        if (s1 == null && s2 == null) {
            return true;
        }
        if (s1 == null || s2 == null) {
            return false;
        }
        int l1 = s1.length();
        int l2 = s2.length();
        if (l1 > l2) {
            return false;
        }
        Map<Character, Integer> characterCountMap = buildMapFromString(s1);
        for (int i = 0; i <= l2 - l1; i++) {
            String substring = s2.substring(i, l1 + i);
            boolean equals = equalsInPermutation(substring, characterCountMap);
            if (equals) {
                return true;
            }
        }
        return false;
    }

    private boolean equalsInPermutation(String s, Map<Character, Integer> characterCountMap) {
        char[] chars = s.toCharArray();
        for (char c : chars) {
            if (!characterCountMap.containsKey(c)) {
                return false;
            }
        }
        AtomicBoolean equals = new AtomicBoolean(true);
        Map<Character, Integer> map = buildMapFromString(s);
        characterCountMap.forEach((k, v) -> {
            Integer count = map.get(k);
            if (!Objects.equals(count, v)) {
                equals.set(false);
            }
        });
        return equals.get();
    }

    private Map<Character, Integer> buildMapFromString(String s) {
        Map<Character, Integer> map = new HashMap<>(16);
        if (s != null) {
            char[] chars = s.toCharArray();
            for (char aChar : chars) {
                int count = map.getOrDefault(aChar, 0);
                map.put(aChar, ++count);
            }
        }
        return map;
    }
}
